Files
httpclient/lib/httpclient.js
2015-08-13 00:43:00 +02:00

264 lines
5.4 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"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();
});
}
};