Skip to content

Commit

Permalink
Merge commit '4e21f1c509c3ee09ea4031c27855ed8e9ddc0d35' into HEAD
Browse files Browse the repository at this point in the history
* commit '4e21f1c509c3ee09ea4031c27855ed8e9ddc0d35':
  Documented FormData support in .send() (#1260)
  Update supported node version to >= 4.0 (#1248)
  Keep nodelay always on
  support TCP_NODELAY option (#1240)
  timeout options.read property is not used.
  grammar misstype (#1234)
  Fix spelling mistake in the docs (#1232)
  Revert test 'fixes' - see PR #1227
  Support passphrase with pfx certificate
  Fix build errors
  Send payload in query string for GET and HEAD shorthand API
  Fix xml tests that broke with mime update
  • Loading branch information
kornelski committed Aug 8, 2017
2 parents 8c95c4f + 4e21f1c commit 9e53357
Show file tree
Hide file tree
Showing 13 changed files with 107 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Readme.md
Expand Up @@ -19,7 +19,7 @@ Works with [browserify](https://github.com/substack/node-browserify) and should
```js
request
.post('/api/pet')
.send({ name: 'Manny', species: 'cat' })
.send({ name: 'Manny', species: 'cat' }) // sends a JSON post body
.set('X-API-Key', 'foobar')
.set('Accept', 'application/json')
.end(function(err, res){
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Expand Up @@ -150,7 +150,7 @@ A typical JSON __POST__ request might look a little like the following, where we
.send('{"name":"tj","pet":"tobi"}')
.end(callback)

Since JSON is undoubtably the most common, it's the _default_! The following example is equivalent to the previous.
Since JSON is undoubtedly the most common, it's the _default_! The following example is equivalent to the previous.

request.post('/user')
.send({ name: 'tj', pet: 'tobi' })
Expand Down
37 changes: 33 additions & 4 deletions docs/test.html
Expand Up @@ -190,14 +190,15 @@ <h1>res.header</h1>
<section class="suite">
<h1>set headers</h1>
<dl>
<dt>should only set headers for ownProperties of header</dt>
<dd><pre><code>try {
<dt class="error">should only set headers for ownProperties of header</dt>
<dd class="error"><pre><code>try {
request
.get(uri + '/echo')
.end(done);
} catch (e) {
done(e)
}</code></pre></dd>
<dd class="error">Error: socket hang up</dd>
</dl>
</section>
<section class="suite">
Expand Down Expand Up @@ -343,7 +344,7 @@ <h1>req.accept(str)</h1>
.accept('xml')
.end(function(err, res){
try {
res.header['accept'].should.equal('application/xml');
res.header['accept'].should.equal('text/xml');
done();
} catch(e) { done(e); }
});</code></pre></dd>
Expand Down Expand Up @@ -1299,7 +1300,7 @@ <h1>request</h1>
.accept('xml')
.end(function(err, res){
try {
assert.equal('application/xml', res.text, res.text);
assert.equal('text/xml', res.text, res.text);
next();
} catch(e) { next(e); }
});</code></pre></dd>
Expand Down Expand Up @@ -1596,6 +1597,22 @@ <h1>request</h1>
assert.deepEqual(res.body, { search: 'Manny', range: '1..5', order: 'desc' });
next();
} catch(e) { next(e); }
});</code></pre></dd>
<dt>GET shorthand payload goes to querystring</dt>
<dd><pre><code>request
.get(uri + '/querystring', {foo: 'FOO', bar: 'BAR'}, function(err, res){
try {
assert.deepEqual(res.body, { foo: 'FOO', bar: 'BAR' });
next();
} catch(e) { next(e); }
});</code></pre></dd>
<dt>HEAD shorthand payload goes to querystring</dt>
<dd><pre><code>request
.head(uri + '/querystring-in-header', {foo: 'FOO', bar: 'BAR'}, function(err, res){
try {
assert.deepEqual(JSON.parse(res.headers.query), { foo: 'FOO', bar: 'BAR' });
next();
} catch(e) { next(e); }
});</code></pre></dd>
<dt>request(method, url)</dt>
<dd><pre><code>request('GET', uri + '/foo').end(function(err, res){
Expand Down Expand Up @@ -2692,6 +2709,18 @@ <h1>request</h1>
<dd><pre><code>request
.get(testEndpoint)
.pfx(pfx)
.end(function(err, res){
assert(res.ok);
assert.strictEqual('Safe and secure!', res.text);
done();
})</code></pre></dd>
<dt>should give a good response with client pfx with passphrase</dt>
<dd><pre><code>request
.get(testEndpoint)
.pfx({
pfx: passpfx,
passphrase: 'test'
})
.end(function(err, res){
assert(res.ok);
assert.strictEqual('Safe and secure!', res.text);
Expand Down
6 changes: 5 additions & 1 deletion index.html
Expand Up @@ -119,7 +119,7 @@ <h2 id="request-basics">Request basics</h2>
.set(&#39;Content-Type&#39;, &#39;application/json&#39;)
.send(&#39;{&quot;name&quot;:&quot;tj&quot;,&quot;pet&quot;:&quot;tobi&quot;}&#39;)
.end(callback)
</code></pre><p>Since JSON is undoubtably the most common, it&#39;s the <em>default</em>! The following example is equivalent to the previous.</p>
</code></pre><p>Since JSON is undoubtedly the most common, it&#39;s the <em>default</em>! The following example is equivalent to the previous.</p>
<pre><code> request.post(&#39;/user&#39;)
.send({ name: &#39;tj&#39;, pet: &#39;tobi&#39; })
.end(callback)
Expand All @@ -140,6 +140,10 @@ <h2 id="request-basics">Request basics</h2>
.send({ name: &#39;tj&#39; })
.send({ pet: &#39;tobi&#39; })
.end(callback)
</code></pre><p>Sending a <a href="https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData"><code>FormData</code></a> object is also supported. The following example will <strong>POST</strong> the content of the HTML form identified by id=&quot;myForm&quot;:</p>
<pre><code> request.post(&#39;/user&#39;)
.send(new FormData(document.getElementById(&#39;myForm&#39;)))
.end(callback)
</code></pre><h2 id="setting-the-content-type-">Setting the <code>Content-Type</code></h2>
<p>The obvious solution is to use the <code>.set()</code> method:</p>
<pre><code> request.post(&#39;/user&#39;)
Expand Down
10 changes: 5 additions & 5 deletions lib/client.js
Expand Up @@ -59,7 +59,7 @@ request.getXHR = function () {
try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
}
throw Error("Browser-only verison of superagent could not find XHR");
throw Error("Browser-only version of superagent could not find XHR");
};

/**
Expand Down Expand Up @@ -169,7 +169,7 @@ request.parseString = parseString;
request.types = {
html: 'text/html',
json: 'application/json',
xml: 'application/xml',
xml: 'text/xml',
urlencoded: 'application/x-www-form-urlencoded',
'form': 'application/x-www-form-urlencoded',
'form-data': 'application/x-www-form-urlencoded'
Expand Down Expand Up @@ -525,10 +525,10 @@ Request.prototype.auth = function(user, pass, options){
this.username = user;
this.password = pass;
break;

case 'bearer': // usage would be .auth(accessToken, { type: 'bearer' })
this.set('Authorization', 'Bearer ' + user);
break;
break;
}
return this;
};
Expand Down Expand Up @@ -807,7 +807,7 @@ request.get = function(url, data, fn){
request.head = function(url, data, fn){
var req = request('HEAD', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (data) req.query(data);
if (fn) req.end(fn);
return req;
};
Expand Down
20 changes: 18 additions & 2 deletions lib/node/index.js
Expand Up @@ -528,7 +528,12 @@ Request.prototype.key = function(cert){
*/

Request.prototype.pfx = function(cert){
this._pfx = cert;
if(typeof cert === 'object' && !Buffer.isBuffer(cert)){
this._pfx = cert.pfx;
this._passphrase = cert.passphrase;
} else {
this._pfx = cert;
}
return this;
};

Expand Down Expand Up @@ -596,13 +601,18 @@ Request.prototype.request = function(){
options.key = this._key;
options.pfx = this._pfx;
options.cert = this._cert;
options.passphrase = this._passphrase;
options.agent = this._agent;

// initiate request
var mod = exports.protocols[url.protocol];

// request
var req = this.req = mod.request(options);

// set tcp no delay
req.setNoDelay(true);

if ('HEAD' != options.method) {
req.setHeader('Accept-Encoding', 'gzip, deflate');
}
Expand Down Expand Up @@ -974,7 +984,13 @@ methods.forEach(function(method){
request[name] = function(url, data, fn){
var req = request(method, url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (data) {
if (method === 'GET' || method === 'HEAD') {
req.query(data);
} else {
req.send(data);
}
}
fn && req.end(fn);
return req;
};
Expand Down
2 changes: 1 addition & 1 deletion lib/request-base.js
Expand Up @@ -108,7 +108,7 @@ RequestBase.prototype.serialize = function serialize(fn){
*
* Value of 0 or false means no timeout.
*
* @param {Number|Object} ms or {response, read, deadline}
* @param {Number|Object} ms or {response, deadline}
* @return {Request} for chaining
* @api public
*/
Expand Down
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -31,7 +31,7 @@
"form-data": "^2.1.1",
"formidable": "^1.1.1",
"methods": "^1.1.1",
"mime": "^1.3.4",
"mime": "^1.3.6",
"qs": "^6.4.0",
"readable-stream": "^2.0.5"
},
Expand Down Expand Up @@ -61,6 +61,6 @@
},
"main": "./lib/node/index.js",
"engines": {
"node": ">= 0.12"
"node": ">= 4.0"
}
}
2 changes: 1 addition & 1 deletion test/basic.js
Expand Up @@ -360,7 +360,7 @@ describe('request', function(){
.accept('xml')
.end(function(err, res){
try {
res.header['accept'].should.equal('application/xml');
res.header['accept'].should.equal('text/xml');
done();
} catch(e) { done(e); }
});
Expand Down
Binary file added test/node/fixtures/passcert.pfx
Binary file not shown.
15 changes: 14 additions & 1 deletion test/node/https.js
Expand Up @@ -10,6 +10,7 @@ var request = require('../..'),
key = fs.readFileSync(__dirname + '/fixtures/key.pem'),
pfx = fs.readFileSync(__dirname + '/fixtures/cert.pfx'),
cert = fs.readFileSync(__dirname + '/fixtures/cert.pem'),
passpfx = fs.readFileSync(__dirname + '/fixtures/passcert.pfx'),
server;


Expand Down Expand Up @@ -77,7 +78,6 @@ describe('https', function(){
})
})


describe('client certificates', function() {
before(function listen(done) {
server = https.createServer({
Expand Down Expand Up @@ -120,6 +120,19 @@ describe('https', function(){
done();
})
})
it('should give a good response with client pfx with passphrase', function(done){
request
.get(testEndpoint)
.pfx({
pfx: passpfx,
passphrase: 'test'
})
.end(function(err, res){
assert(res.ok);
assert.strictEqual('Safe and secure!', res.text);
done();
})
})
})

describe('.agent', function () {
Expand Down
22 changes: 21 additions & 1 deletion test/request.js
Expand Up @@ -295,7 +295,7 @@ it('request .accept() with xml', function(next){
.accept('xml')
.end(function(err, res){
try {
assert.equal('application/xml', res.text, res.text);
assert.equal('text/xml', res.text, res.text);
next();
} catch(e) { next(e); }
});
Expand Down Expand Up @@ -656,6 +656,26 @@ it('GET querystring with strings and objects', function(next){
});
});

it('GET shorthand payload goes to querystring', function(next){
request
.get(uri + '/querystring', {foo: 'FOO', bar: 'BAR'}, function(err, res){
try {
assert.deepEqual(res.body, { foo: 'FOO', bar: 'BAR' });
next();
} catch(e) { next(e); }
});
});

it('HEAD shorthand payload goes to querystring', function(next){
request
.head(uri + '/querystring-in-header', {foo: 'FOO', bar: 'BAR'}, function(err, res){
try {
assert.deepEqual(JSON.parse(res.headers.query), { foo: 'FOO', bar: 'BAR' });
next();
} catch(e) { next(e); }
});
});

it('request(method, url)', function(next){
request('GET', uri + '/foo').end(function(err, res){
try {
Expand Down
5 changes: 5 additions & 0 deletions test/support/server.js
Expand Up @@ -227,6 +227,11 @@ app.get('/querystring', function(req, res){
res.send(req.query);
});

app.get('/querystring-in-header', function(req, res){
res.set('query', JSON.stringify(req.query));
res.send();
});

app.get('/echo-header/:field', function(req, res){
res.send(req.headers[req.params.field]);
});
Expand Down

0 comments on commit 9e53357

Please sign in to comment.