AJ ONeal
6 years ago
commit
956c16e48c
9 changed files with 335 additions and 0 deletions
@ -0,0 +1,41 @@ |
|||
Copyright 2018 AJ ONeal |
|||
|
|||
This is open source software; you can redistribute it and/or modify it under the |
|||
terms of either: |
|||
|
|||
a) the "MIT License" |
|||
b) the "Apache-2.0 License" |
|||
|
|||
MIT License |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
of this software and associated documentation files (the "Software"), to deal |
|||
in the Software without restriction, including without limitation the rights |
|||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
copies of the Software, and to permit persons to whom the Software is |
|||
furnished to do so, subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in all |
|||
copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|||
SOFTWARE. |
|||
|
|||
Apache-2.0 License Summary |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); |
|||
you may not use this file except in compliance with the License. |
|||
You may obtain a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, |
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
See the License for the specific language governing permissions and |
|||
limitations under the License. |
@ -0,0 +1,16 @@ |
|||
# µRequest - Minimalist HTTP client |
|||
|
|||
A minimal drop-in replacement for request with 0 dependenciese. |
|||
|
|||
## Super simple to use |
|||
|
|||
µRequest is designed to be a minimal drop-in replacement for request. |
|||
|
|||
```js |
|||
var request = require('urequest'); |
|||
request('http://www.google.com', function (error, response, body) { |
|||
console.log('error:', error); // Print the error if one occurred |
|||
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received |
|||
console.log('body:', body); // Print the HTML for the Google homepage. |
|||
}); |
|||
``` |
@ -0,0 +1,7 @@ |
|||
'use strict'; |
|||
|
|||
// if NODE_DEBUG contains 'urequest' then this should print out 'DEBUG ON for urequest'
|
|||
// NODE_DEBUG="urequest" node examples/debug.js
|
|||
//
|
|||
//require('urequest');
|
|||
require('../'); |
@ -0,0 +1,15 @@ |
|||
'use strict'; |
|||
|
|||
//var request = require('urequest');
|
|||
var request = require('../'); |
|||
|
|||
// will redirect to https://www.github.com and then https://github.com
|
|||
request('http://www.github.com', 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('Final URI:', response.request.uri); // The final URI
|
|||
console.log('Body Length:', body.length); // body length
|
|||
}); |
@ -0,0 +1,9 @@ |
|||
'use strict'; |
|||
|
|||
//var request = require('urequest');
|
|||
var request = require('../'); |
|||
request('http://www.google.com', function (error, response, body) { |
|||
console.log('error:', error); // Print the error if one occurred
|
|||
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
|
|||
console.log('body:', body); // Print the HTML for the Google homepage.
|
|||
}); |
@ -0,0 +1,9 @@ |
|||
'use strict'; |
|||
|
|||
//var request = require('urequest');
|
|||
var request = require('../'); |
|||
request('https://www.google.com', function (error, response, body) { |
|||
console.log('error:', error); // Print the error if one occurred
|
|||
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
|
|||
console.log('body:', body); // Print the HTML for the Google homepage.
|
|||
}); |
@ -0,0 +1,16 @@ |
|||
'use strict'; |
|||
|
|||
//var request = require('urequest');
|
|||
var request = require('../'); |
|||
|
|||
// would normally redirect to https://www.github.com and then https://github.com
|
|||
request({ uri: 'https://www.github.com', followRedirect: false }, function (error, response, body) { |
|||
if (error) { |
|||
console.log('error:', error); // Print the error if one occurred
|
|||
return; |
|||
} |
|||
console.log('URI:', response.request.uri); // The final URI
|
|||
console.log('statusCode:', response.statusCode); // Should be 301 or 302
|
|||
console.log('Location:', response.headers.location); // The redirect
|
|||
console.log('Body:', body || JSON.stringify(body)); |
|||
}); |
@ -0,0 +1,196 @@ |
|||
'use strict'; |
|||
|
|||
var http = require('http'); |
|||
var https = require('https'); |
|||
var url = require('url'); |
|||
|
|||
function debug() { |
|||
if (module.exports.debug) { |
|||
console.log.apply(console, arguments); |
|||
} |
|||
} |
|||
|
|||
function applyUrl(opts, urlstr) { |
|||
var urlObj = url.parse(urlstr); |
|||
opts.url = opts.uri = urlstr; |
|||
Object.keys(urlObj).forEach(function (key) { |
|||
opts[key] = urlObj[key]; |
|||
}); |
|||
return opts; |
|||
} |
|||
|
|||
function mergeOrDelete(defaults, updates) { |
|||
Object.keys(defaults).forEach(function (key) { |
|||
if (!(key in updates)) { |
|||
updates[key] = defaults[key]; |
|||
return; |
|||
} |
|||
|
|||
// neither accept the prior default nor define an explicit value
|
|||
// CRDT probs...
|
|||
if ('undefined' === typeof updates[key]) { |
|||
delete updates[key]; |
|||
} else if ('object' === typeof defaults[key] && 'object' === typeof updates[key]) { |
|||
updates[key] = mergeOrDelete(defaults[key], updates[key]); |
|||
} |
|||
}); |
|||
|
|||
return updates; |
|||
} |
|||
|
|||
function setDefaults(defs) { |
|||
defs = defs || {}; |
|||
|
|||
function urequest(opts, cb) { |
|||
var req; |
|||
// request.js behavior:
|
|||
// encoding: null + json ? unknown
|
|||
// json => attempt to parse, fail silently
|
|||
// encoding => buffer.toString(encoding)
|
|||
// null === encoding => Buffer.concat(buffers)
|
|||
if ('string' === typeof opts) { |
|||
opts = { url: opts }; |
|||
} |
|||
if (!opts.method) { |
|||
opts.method = 'GET'; |
|||
} |
|||
if (!opts.method) { |
|||
opts.method = 'GET'; |
|||
} |
|||
if (opts.url || opts.uri) { |
|||
opts = applyUrl(opts, opts.url || opts.uri); |
|||
} |
|||
function onResponse(resp) { |
|||
var encoding = opts.encoding || defs.encoding; |
|||
var followRedirect; |
|||
Object.keys(defs).forEach(function (key) { |
|||
if (key in opts && 'undefined' !== typeof opts[key]) { |
|||
return; |
|||
} |
|||
opts[key] = defs[key]; |
|||
}); |
|||
followRedirect = opts.followRedirect; |
|||
|
|||
resp.request = req; |
|||
resp.request.uri = opts.uri; |
|||
if (resp.headers.location && opts.followRedirect) { |
|||
debug('Following redirect: ' + resp.headers.location); |
|||
if (opts.followAllRedirects || -1 !== [ 301, 302 ].indexOf(resp.statusCode)) { |
|||
followRedirect = true; |
|||
} |
|||
if (opts._redirectCount >= opts.maxRedirects) { |
|||
followRedirect = false; |
|||
} |
|||
if ('function' === opts.followRedirect) { |
|||
if (!opts.followRedirect(resp)) { |
|||
followRedirect = false; |
|||
} |
|||
} |
|||
if (!opts.followOriginalHttpMethod) { |
|||
opts.method = 'GET'; |
|||
opts.body = null; |
|||
} |
|||
if (followRedirect) { |
|||
opts.url = resp.headers.location; |
|||
return urequest(opts, cb); |
|||
} |
|||
if (opts.removeRefererHeader && opts.headers) { |
|||
delete opts.headers.referer; |
|||
} |
|||
} |
|||
if (null === encoding) { |
|||
resp._body = []; |
|||
} else { |
|||
resp.body = ''; |
|||
} |
|||
resp._bodyLength = 0; |
|||
resp.on('data', function (chunk) { |
|||
if ('string' === typeof resp.body) { |
|||
resp.body += chunk.toString(encoding); |
|||
} else { |
|||
resp._body.push(chunk); |
|||
resp._bodyLength += chunk.length; |
|||
} |
|||
}); |
|||
resp.on('end', function () { |
|||
if ('string' !== typeof resp.body) { |
|||
if (1 === resp._body.length) { |
|||
resp.body = resp._body[0]; |
|||
} else { |
|||
resp.body = Buffer.concat(resp._body, resp._bodyLength); |
|||
} |
|||
resp._body = null; |
|||
} |
|||
if (opts.json && 'string' === typeof resp.body) { |
|||
// TODO I would parse based on Content-Type
|
|||
// but request.js doesn't do that.
|
|||
try { |
|||
resp.body = JSON.parse(resp.body); |
|||
} catch(e) { |
|||
// ignore
|
|||
} |
|||
} |
|||
cb(null, resp, resp.body); |
|||
}); |
|||
} |
|||
|
|||
if (!opts.protocol) { |
|||
opts.protocol = 'https:'; |
|||
} |
|||
if ('https:' === opts.protocol) { |
|||
req = https.request(opts, onResponse); |
|||
} else if ('http:' === opts.protocol) { |
|||
req = http.request(opts, onResponse); |
|||
} else { |
|||
throw new Error("unknown protocol: '" + opts.protocol + "'"); |
|||
} |
|||
req.on('error', function (e) { |
|||
cb(e); |
|||
}); |
|||
if (opts.body) { |
|||
if (true === opts.json) { |
|||
req.end(JSON.stringify(opts.json)); |
|||
} else { |
|||
req.end(opts.body); |
|||
} |
|||
} else if (opts.json && true !== opts.json) { |
|||
req.end(JSON.stringify(opts.json)); |
|||
} else { |
|||
req.end(); |
|||
} |
|||
} |
|||
|
|||
urequest.defaults = function (_defs) { |
|||
_defs = mergeOrDelete(defs, _defs); |
|||
return setDefaults(_defs); |
|||
}; |
|||
[ 'get', 'put', 'post', 'patch', 'delete', 'head', 'options' ].forEach(function (method) { |
|||
urequest[method] = function (obj) { |
|||
if ('string' === typeof obj) { |
|||
obj = { url: obj }; |
|||
} |
|||
obj.method = method.toUpperCase(); |
|||
urequest(obj); |
|||
}; |
|||
}); |
|||
urequest.del = urequest.delete; |
|||
|
|||
return urequest; |
|||
} |
|||
|
|||
module.exports = setDefaults({ |
|||
sendImmediately: true |
|||
, method: 'GET' |
|||
, headers: {} |
|||
, useQuerystring: false |
|||
, followRedirect: true |
|||
, followAllRedirects: false |
|||
, followOriginalHttpMethod: false |
|||
, maxRedirects: 10 |
|||
, removeRefererHeader: false |
|||
//, encoding: undefined
|
|||
, gzip: false |
|||
}); |
|||
module.exports.debug = (-1 !== (process.env.NODE_DEBUG||'').split(/\s+/g).indexOf('urequest')); |
|||
|
|||
debug("DEBUG ON for urequest"); |
@ -0,0 +1,26 @@ |
|||
{ |
|||
"name": "urequest", |
|||
"version": "1.0.0", |
|||
"description": "A lightweight drop-in replacement for request", |
|||
"main": "index.js", |
|||
"directories": { |
|||
"example": "examples" |
|||
}, |
|||
"scripts": { |
|||
"test": "echo \"Error: no test specified\" && exit 1" |
|||
}, |
|||
"repository": { |
|||
"type": "git", |
|||
"url": "https://git.ppl.family/ppl/urequest.js.git" |
|||
}, |
|||
"keywords": [ |
|||
"request", |
|||
"lightweight", |
|||
"alternative", |
|||
"http", |
|||
"https", |
|||
"call" |
|||
], |
|||
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)", |
|||
"license": "(MIT OR Apache-2.0)" |
|||
} |
Loading…
Reference in new issue