www-form support, add *Content-Length by default
This commit is contained in:
parent
8758964610
commit
b5714c6a65
73
README.md
73
README.md
|
@ -23,10 +23,83 @@ request('http://www.google.com', function (error, response, body) {
|
||||||
|
|
||||||
## Table of contents
|
## Table of contents
|
||||||
|
|
||||||
|
- [Forms](#forms)
|
||||||
- [Custom HTTP Headers](#custom-http-headers)
|
- [Custom HTTP Headers](#custom-http-headers)
|
||||||
- [Unix Domain Sockets](#unix-domain-sockets)
|
- [Unix Domain Sockets](#unix-domain-sockets)
|
||||||
- [**All Available Options**](#requestoptions-callback)
|
- [**All Available Options**](#requestoptions-callback)
|
||||||
|
|
||||||
|
## Forms
|
||||||
|
|
||||||
|
`urequest` supports `application/x-www-form-urlencoded` and `multipart/form-data` form uploads.
|
||||||
|
<!-- For `multipart/related` refer to the `multipart` API. -->
|
||||||
|
|
||||||
|
#### application/x-www-form-urlencoded (URL-Encoded Forms)
|
||||||
|
|
||||||
|
URL-encoded forms are simple.
|
||||||
|
|
||||||
|
```js
|
||||||
|
request.post('http://service.com/upload', {form:{key:'value'}})
|
||||||
|
// or
|
||||||
|
request.post({url:'http://service.com/upload', form: {key:'value'}}, function(err,httpResponse,body){ /* ... */ })
|
||||||
|
```
|
||||||
|
<!--
|
||||||
|
// or
|
||||||
|
request.post('http://service.com/upload').form({key:'value'})
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
#### multipart/form-data (Multipart Form Uploads)
|
||||||
|
|
||||||
|
For `multipart/form-data` we use the [form-data](https://github.com/form-data/form-data) library by [@felixge](https://github.com/felixge). For the most cases, you can pass your upload form data via the `formData` option.
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
var formData = {
|
||||||
|
// Pass a simple key-value pair
|
||||||
|
my_field: 'my_value',
|
||||||
|
// Pass data via Buffers
|
||||||
|
my_buffer: Buffer.from([1, 2, 3]),
|
||||||
|
// Pass data via Streams
|
||||||
|
my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),
|
||||||
|
// Pass multiple values /w an Array
|
||||||
|
attachments: [
|
||||||
|
fs.createReadStream(__dirname + '/attachment1.jpg'),
|
||||||
|
fs.createReadStream(__dirname + '/attachment2.jpg')
|
||||||
|
],
|
||||||
|
// Pass optional meta-data with an 'options' object with style: {value: DATA, options: OPTIONS}
|
||||||
|
// Use case: for some types of streams, you'll need to provide "file"-related information manually.
|
||||||
|
// See the `form-data` README for more information about options: https://github.com/form-data/form-data
|
||||||
|
custom_file: {
|
||||||
|
value: fs.createReadStream('/dev/urandom'),
|
||||||
|
options: {
|
||||||
|
filename: 'topsecret.jpg',
|
||||||
|
contentType: 'image/jpeg'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
request.post({url:'http://service.com/upload', formData: formData}, function optionalCallback(err, httpResponse, body) {
|
||||||
|
if (err) {
|
||||||
|
return console.error('upload failed:', err);
|
||||||
|
}
|
||||||
|
console.log('Upload successful! Server responded with:', body);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<!--
|
||||||
|
|
||||||
|
For advanced cases, you can access the form-data object itself via `r.form()`. This can be modified until the request is fired on the next cycle of the event-loop. (Note that this calling `form()` will clear the currently set form data for that request.)
|
||||||
|
|
||||||
|
```js
|
||||||
|
// NOTE: Advanced use-case, for normal use see 'formData' usage above
|
||||||
|
var r = request.post('http://service.com/upload', function optionalCallback(err, httpResponse, body) {...})
|
||||||
|
var form = r.form();
|
||||||
|
form.append('my_field', 'my_value');
|
||||||
|
form.append('my_buffer', Buffer.from([1, 2, 3]));
|
||||||
|
form.append('custom_file', fs.createReadStream(__dirname + '/unicycle.jpg'), {filename: 'unicycle.jpg'});
|
||||||
|
```
|
||||||
|
-->
|
||||||
|
|
||||||
|
See the [form-data README](https://github.com/form-data/form-data) for more information & examples.
|
||||||
|
|
||||||
## Custom HTTP Headers
|
## Custom HTTP Headers
|
||||||
|
|
||||||
HTTP Headers, such as `User-Agent`, can be set in the `options` object.
|
HTTP Headers, such as `User-Agent`, can be set in the `options` object.
|
||||||
|
|
|
@ -24,7 +24,6 @@ request(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('statusCode:', response.statusCode); // The final statusCode
|
console.log('statusCode:', response.statusCode); // The final statusCode
|
||||||
console.log('Final href:', response.request.uri.href); // The final URI
|
|
||||||
console.log('Body Length:', body.length); // body length
|
console.log('Body Length:', body.length); // body length
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
//var request = require('@coolaj86/urequest');
|
||||||
|
// To check and make sure the outputs are the same
|
||||||
|
//var request = require('request');
|
||||||
|
var request = require('../');
|
||||||
|
|
||||||
|
// will redirect to https://www.github.com and then https://github.com
|
||||||
|
//request('http://www.github.com', function (error, response, body) {
|
||||||
|
request(
|
||||||
|
{ url: 'http://postb.in/2meyt50C'
|
||||||
|
, headers: { 'X-Foo': 'Bar' }
|
||||||
|
, form: { foo: 'bar', baz: 'qux' }
|
||||||
|
}
|
||||||
|
, function (error, response, body) {
|
||||||
|
if (error) {
|
||||||
|
console.log('error:', error); // Print the error if one occurred
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('statusCode:', response.statusCode); // The final statusCode
|
||||||
|
console.log('Body Length:', body.length); // body length
|
||||||
|
}
|
||||||
|
);
|
30
index.js
30
index.js
|
@ -163,6 +163,15 @@ function setDefaults(defs) {
|
||||||
}
|
}
|
||||||
} else if (opts.json && true !== opts.json) {
|
} else if (opts.json && true !== opts.json) {
|
||||||
_body = JSON.stringify(opts.json);
|
_body = JSON.stringify(opts.json);
|
||||||
|
} else if (opts.form) {
|
||||||
|
_body = Object.keys(opts.form).filter(function (key) {
|
||||||
|
if ('undefined' !== typeof opts.form[key]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}).map(function (key) {
|
||||||
|
return encodeURIComponent(key) + '=' + encodeURIComponent(String(opts.form[key]));
|
||||||
|
}).join('&');
|
||||||
|
opts.headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||||
}
|
}
|
||||||
if ('string' === typeof _body) {
|
if ('string' === typeof _body) {
|
||||||
_body = Buffer.from(_body);
|
_body = Buffer.from(_body);
|
||||||
|
@ -175,8 +184,8 @@ function setDefaults(defs) {
|
||||||
finalOpts.headers = opts.headers;
|
finalOpts.headers = opts.headers;
|
||||||
if (_body) {
|
if (_body) {
|
||||||
// Most APIs expect (or require) Content-Length except in the case of multipart uploads
|
// Most APIs expect (or require) Content-Length except in the case of multipart uploads
|
||||||
// chunked is generally only well-supported downstream
|
// Transfer-Encoding: Chunked (the default) is generally only well-supported downstream
|
||||||
//finalOpts.headers['Content-Length'] = _body.byteLength || _body.length;
|
finalOpts.headers['Content-Length'] = _body.byteLength || _body.length;
|
||||||
}
|
}
|
||||||
if (opts.formData) {
|
if (opts.formData) {
|
||||||
try {
|
try {
|
||||||
|
@ -192,7 +201,17 @@ function setDefaults(defs) {
|
||||||
try {
|
try {
|
||||||
form = new MyFormData();
|
form = new MyFormData();
|
||||||
Object.keys(opts.formData).forEach(function (key) {
|
Object.keys(opts.formData).forEach(function (key) {
|
||||||
form.append(key, opts.formData[key]);
|
function add(key, data, opts) {
|
||||||
|
if (data.value) { opts = data.options; data = data.value; }
|
||||||
|
form.append(key, data, opts);
|
||||||
|
}
|
||||||
|
if (Array.isArray(opts.formData[key])) {
|
||||||
|
opts.formData[key].forEach(function (data) {
|
||||||
|
add(key, data);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
add(key, opts.formData[key]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
cb(e);
|
cb(e);
|
||||||
|
@ -307,7 +326,11 @@ function setDefaults(defs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opts.body || opts.json || opts.form || opts.formData) {
|
||||||
|
reqOpts.method = (reqOpts.method || 'POST').toUpperCase();
|
||||||
|
} else {
|
||||||
reqOpts.method = (reqOpts.method || 'GET').toUpperCase();
|
reqOpts.method = (reqOpts.method || 'GET').toUpperCase();
|
||||||
|
}
|
||||||
reqOpts.headers = reqOpts.headers || {};
|
reqOpts.headers = reqOpts.headers || {};
|
||||||
|
|
||||||
// crazy case for easier testing
|
// crazy case for easier testing
|
||||||
|
@ -360,6 +383,7 @@ module.exports._keys = Object.keys(_defaults).concat([
|
||||||
'encoding'
|
'encoding'
|
||||||
, 'body'
|
, 'body'
|
||||||
, 'json'
|
, 'json'
|
||||||
|
, 'form'
|
||||||
, 'formData'
|
, 'formData'
|
||||||
, 'FormData'
|
, 'FormData'
|
||||||
]);
|
]);
|
||||||
|
|
Loading…
Reference in New Issue