Initial commit
This commit is contained in:
263
lib/httpclient.js
Normal file
263
lib/httpclient.js
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
var http = require("http");
|
||||||
|
var https = require("https");
|
||||||
|
var url = require("url");
|
||||||
|
|
||||||
|
|
||||||
|
function Cookie(rawCookie) {
|
||||||
|
var cookieRegex = /([^,; =]+)(?:=([^;]*)(?:[ ;]+|$))/g;
|
||||||
|
var match;
|
||||||
|
|
||||||
|
var cookie = {};
|
||||||
|
|
||||||
|
while ((match = cookieRegex.exec(rawCookie)) !== null) {
|
||||||
|
var key = match[1];
|
||||||
|
var value = match[2];
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case "Path" :
|
||||||
|
cookie.path = value;
|
||||||
|
break;
|
||||||
|
case "Domain" :
|
||||||
|
cookie.domain = value;
|
||||||
|
break;
|
||||||
|
case "Expires" :
|
||||||
|
this.expires = Date.parse(value);
|
||||||
|
break;
|
||||||
|
case "Max-Age" :
|
||||||
|
cookie.maxAge = Number.parseInt(value);
|
||||||
|
break;
|
||||||
|
case "Secured" :
|
||||||
|
cookie.secured = true;
|
||||||
|
break;
|
||||||
|
case "Http-Only" :
|
||||||
|
cookie.httpOnly = true;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
cookie.name = key;
|
||||||
|
cookie.value = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
var CookieJar = function () {
|
||||||
|
var cookies = new Map();
|
||||||
|
|
||||||
|
this.get = function (path) {
|
||||||
|
var cookieString = "";
|
||||||
|
|
||||||
|
if (cookies.has(path)) {
|
||||||
|
var currentDate = new Date();
|
||||||
|
|
||||||
|
cookies.get(path).forEach( function (value, key, map) {
|
||||||
|
if ((value.expires !== undefined && value.expires < currentDate)
|
||||||
|
|| (value.maxAge !== undefined && currentDate.setSeconds(currentDate.getSeconds() + value.maxAge) < new Date())) {
|
||||||
|
map.delete(key);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cookieString += value.name + "=" + value.value +"; ";
|
||||||
|
}
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cookieString;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.update = function (_cookie) {
|
||||||
|
var cookie = Cookie(_cookie);
|
||||||
|
|
||||||
|
var path = cookie.path ? cookie.path.toUpperCase() : "/";
|
||||||
|
|
||||||
|
if (!cookies.has(path)) {
|
||||||
|
cookies.set(path, new Map());
|
||||||
|
}
|
||||||
|
|
||||||
|
var deleteCookie = ((cookie.maxAge !== undefined && cookie.maxAge <= 0)
|
||||||
|
|| (cookie.expires !== undefined && cookie.expires < new Date()));
|
||||||
|
|
||||||
|
if (deleteCookie) {
|
||||||
|
if (cookies.get(path).has(cookie.name)) {
|
||||||
|
cookies.get(path).delete(cookie.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!cookies.get(path).has(cookie.name)) {
|
||||||
|
cookies.get(path).set(cookie.name, cookie);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cookies.get(path).set(cookie.name, cookie);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module.exports.HttpClient = function Browser (_baseUrl, _headers) {
|
||||||
|
var baseUrl = null;
|
||||||
|
var instance = this;
|
||||||
|
|
||||||
|
//CookieJar and custom headers
|
||||||
|
var cookieJar = new CookieJar();
|
||||||
|
this.headers = {};
|
||||||
|
|
||||||
|
if (_baseUrl) {
|
||||||
|
baseUrl = url.parse(_baseUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_headers) {
|
||||||
|
this.headers = _headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.headers["User-Agent"] === undefined) {
|
||||||
|
this.headers["User-Agent"] = "HttpClient/1.0.0 (" + os.type() + " " + os.release()+")";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.headers["Accept-Language"] === undefined) {
|
||||||
|
this.headers["Accept-Language"] = "en-US";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.headers["Accept"] === undefined) {
|
||||||
|
this.headers["Accept"] = "text/plain,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.headers["Accept-Encoding"] === undefined) {
|
||||||
|
this.headers["Accept-Encoding"] = "gzip,deflate";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.get = function (_path, _querystring) {
|
||||||
|
return query({
|
||||||
|
method : "GET",
|
||||||
|
path : _path,
|
||||||
|
querystring : _querystring,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.post = function(_path, _data) {
|
||||||
|
return query({
|
||||||
|
method : "POST",
|
||||||
|
path : _path,
|
||||||
|
data : _data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.put = function(_path, _data) {
|
||||||
|
return query({
|
||||||
|
method : "PUT",
|
||||||
|
path : _path,
|
||||||
|
data : _data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.delete = function(_path, _querystring) {
|
||||||
|
return query({
|
||||||
|
method : "DELETE",
|
||||||
|
path : _path,
|
||||||
|
querystring : _querystring
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.patch = function(_path, _data) {
|
||||||
|
return query({
|
||||||
|
method : "PATCH",
|
||||||
|
path : _path,
|
||||||
|
data : _data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function query(_request) {
|
||||||
|
var pathUrl = url.parse(_request.path);
|
||||||
|
|
||||||
|
pathUrl.headers = instance.headers;
|
||||||
|
|
||||||
|
var cookies = cookieJar.get(pathUrl.pathname);
|
||||||
|
|
||||||
|
if ( pathUrl.pathname !== "/") {
|
||||||
|
cookies += cookieJar.get("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cookies) {
|
||||||
|
pathUrl.headers.Cookies = cookies;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Complete the url with the base one if a path was provided
|
||||||
|
if (baseUrl !== null && pathUrl.protocol === null) {
|
||||||
|
pathUrl.protocol = baseUrl.protocol;
|
||||||
|
pathUrl.hostname = baseUrl.hostname;
|
||||||
|
pathUrl.auth = baseUrl.auth;
|
||||||
|
pathUrl.port = baseUrl.port;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise(function(fulfill, reject) {
|
||||||
|
var protocol;
|
||||||
|
|
||||||
|
if (pathUrl.protocol === "https:") {
|
||||||
|
protocol = https;
|
||||||
|
|
||||||
|
if (pathUrl.rejectUnauthorized === null || pathUrl.rejectUnauthorized === undefined) {
|
||||||
|
pathUrl.rejectUnauthorized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pathUrl.port) {
|
||||||
|
pathUrl.port = 443;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
protocol = http;
|
||||||
|
|
||||||
|
if (!pathUrl.port) {
|
||||||
|
pathUrl.port = 80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pathUrl.method = _request.method;
|
||||||
|
|
||||||
|
var request = protocol.request(pathUrl, function(response) {
|
||||||
|
if (response.statusCode < 300) {
|
||||||
|
if (response.headers["set-cookie"]) {
|
||||||
|
for (let i = 0 ; i < response.headers["set-cookie"].length ; ++i) {
|
||||||
|
cookieJar.update(response.headers["set-cookie"][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let decoder;
|
||||||
|
|
||||||
|
if (response.headers["content-encoding"] === "gzip") {
|
||||||
|
decoder = zlib.createGunzip();
|
||||||
|
response.pipe(decoder);
|
||||||
|
}
|
||||||
|
else if (response.headers["content-encoding"] === "deflate") {
|
||||||
|
decoder = zlib.createInfate();
|
||||||
|
response.pipe(decoder);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
decoder = response;
|
||||||
|
response.setEncoding("utf8");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fulfill(decoder);
|
||||||
|
}
|
||||||
|
else if (response.statusCode < 400) {
|
||||||
|
instance.get(response.headers.location)
|
||||||
|
.then(fulfill)
|
||||||
|
.catch(reject);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reject(response.statusCode, response);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
request.on("error", function(error) {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (_request.data) {
|
||||||
|
request.write(_request.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
request.end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
21
package.json
Normal file
21
package.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "httpclient",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Wrapper around http and https request with cookie container",
|
||||||
|
"main": "lib/httpclient.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://lab.cherboiche.org/iojs/httpclient.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"http",
|
||||||
|
"https",
|
||||||
|
"request",
|
||||||
|
"cookies"
|
||||||
|
],
|
||||||
|
"author": "boudin",
|
||||||
|
"license": "GPL-3.0"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user